/*
 * Copyright 2010, Andrew M Gibson
 *
 * www.andygibson.net
 *
 * This file is part of DataValve.
 *
 * DataValve is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * DataValve is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with DataValve.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fluttercode.datavalve.provider.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 把ResultSet当前行的一列转换为一个对象
 *
 * @param <T> The type of the scalar
 */
public class ScalarMapper<T> implements ResultSetObjectMapper<T> {

    /** The column number to retrieve. */
    private final int columnIndex;

    /**
     * The column name to retrieve.
     * Either columnName or columnIndex will be used but never both.
     */
    private final String columnName;

    /**
     * Creates a new instance of ScalarMapper.
     * The first column will be returned from <code>handle()</code>.
     */
    public ScalarMapper() {
        this(1, null);
    }

    /**
     * Creates a new instance of ScalarMapper.
     *
     * @param columnIndex The index of the column to retrieve from the <code>ResultSet</code>.
     */
    public ScalarMapper(int columnIndex) {
        this(columnIndex, null);
    }

    /**
     * Creates a new instance of ScalarMapper.
     *
     * @param columnName The name of the column to retrieve from the <code>ResultSet</code>.
     */
    public ScalarMapper(String columnName) {
        this(1, columnName);
    }

    /**
     * Helper constructor
     *
     * @param columnIndex The index of the column to retrieve from the <code>ResultSet</code>.
     * @param columnName The name of the column to retrieve from the <code>ResultSet</code>.
     */
    private ScalarMapper(int columnIndex, String columnName) {
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    /**
     * Returns one <code>ResultSet</code> column as an object via the
     * <code>ResultSet.getObject()</code> method that performs type
     * conversions.
     *
     * @param rs <code>ResultSet</code> to process.
     * @return The column or <code>null</code> if there are no rows in the <code>ResultSet</code>.
     *
     * @throws SQLException if a database access error occurs
     * @throws ClassCastException if the class datatype does not match the column type
     */
    // We assume that the user has picked the correct type to match the column
    // so getObject will return the appropriate type and the cast will succeed.
    @Override
    public T createObjectFromResultSet(ResultSet rs) throws SQLException {
        if (this.columnName == null) {
            return (T) rs.getObject(this.columnIndex);
        }
        return (T) rs.getObject(this.columnName);
    }
}
